"""
敏感词检测模块
用于检测文本中的违规词汇
"""

import re
import logging
from typing import List, Tuple, Set

logger = logging.getLogger(__name__)


class SensitiveWordFilter:
    """敏感词过滤器"""
    
    def __init__(self):
        """初始化敏感词库"""
        # 🔥 违规词库（按类别分类）
        self.word_categories = {
            # 广告类
            'advertising': [
                'QQ群', 'qq群', 'QQ号', 'qq号', 'QQ加', 'qq加',
                '微信号', '微信加', '加微信', 'VX号', 'vx号',
                '扫码', '二维码', '加群', '进群',
                '加我', '私聊', '联系我', '找我',
                '代购', '代理', '招代理', '兼职',
                '刷单', '点赞', '关注', '转发',
            ],
            
            # 色情低俗类
            'pornography': [
                '约炮', '开房', '一夜情', '包养',
                '性服务', '上门服务', '特殊服务',
                '色情', '黄色', '裸聊', '视频裸聊',
            ],
            
            # 赌博类
            'gambling': [
                '赌博', '博彩', '六合彩', '时时彩',
                '赌场', '赌钱', '网赌', '菠菜',
                '百家乐', '21点', '德州扑克',
            ],
            
            # 违法犯罪类
            'illegal': [
                '毒品', '大麻', '海洛因', '冰毒',
                '枪支', '军火', '炸药', '爆炸物',
                '假证', '办证', '假币', '洗钱',
                '走私', '贩毒', '贩卖',
            ],
            
            # 诈骗类
            'fraud': [
                '刷信誉', '刷钻', '刷皇冠', '刷好评',
                '贷款', '无抵押', '身份证贷款', '快速贷款',
                '办卡', '信用卡套现', '养卡',
                '中奖', '恭喜中奖', '免费领取',
            ],
            
            # 时政类（敏感话题）
            'politics': [
                '法轮功', '达赖', '藏独', '疆独',
                '反共', '反华', '游行', '示威',
            ],
            
            # 辱骂侮辱类
            'abuse': [
                '傻逼', '操你妈', 'CNM', 'nmsl',
                '去死', '该死', '死全家',
                '智障', '脑残', '废物', '垃圾',
            ],
        }
        
        # 🔥 合并所有敏感词为一个列表
        self.all_words: Set[str] = set()
        for words in self.word_categories.values():
            self.all_words.update(words)
        
        # 🔥 编译正则表达式（支持变形检测）
        self._compile_patterns()
        
        logger.info(f"✅ 敏感词库加载完成，共 {len(self.all_words)} 个敏感词")
    
    def _compile_patterns(self):
        """编译敏感词的正则表达式模式"""
        self.patterns = []
        
        # 为每个敏感词创建正则模式（支持变形）
        for word in self.all_words:
            # 基础模式：直接匹配
            pattern = re.escape(word)
            
            # 支持变形：在字符之间插入空格、符号等
            # 例如：QQ群 -> Q Q 群、Q.Q.群 等
            flexible_pattern = ''
            for char in word:
                flexible_pattern += re.escape(char) + r'[\s\.\-_]*'
            flexible_pattern = flexible_pattern.rstrip(r'[\s\.\-_]*')
            
            # 编译正则表达式（不区分大小写）
            try:
                self.patterns.append(re.compile(pattern, re.IGNORECASE))
                self.patterns.append(re.compile(flexible_pattern, re.IGNORECASE))
            except Exception as e:
                logger.error(f"编译敏感词失败: {word}, 错误: {e}")
    
    def check_text(self, text: str) -> Tuple[bool, List[str], str]:
        """
        检测文本是否包含敏感词
        
        Args:
            text: 要检测的文本
            
        Returns:
            (is_sensitive, matched_words, category)
            - is_sensitive: 是否包含敏感词
            - matched_words: 匹配到的敏感词列表
            - category: 违规类别
        """
        if not text:
            return False, [], ''
        
        matched_words = []
        matched_category = ''
        
        # 🔥 使用正则表达式匹配
        for pattern in self.patterns:
            matches = pattern.findall(text)
            if matches:
                matched_words.extend(matches)
        
        # 🔥 去重
        matched_words = list(set(matched_words))
        
        # 🔥 确定违规类别
        if matched_words:
            for category, words in self.word_categories.items():
                for word in words:
                    if any(word.lower() in m.lower() for m in matched_words):
                        matched_category = category
                        break
                if matched_category:
                    break
        
        is_sensitive = len(matched_words) > 0
        
        if is_sensitive:
            logger.warning(f"⚠️ 检测到敏感词: {matched_words}, 类别: {matched_category}")
        
        return is_sensitive, matched_words, matched_category
    
    def replace_sensitive_words(self, text: str, replace_char: str = '*') -> str:
        """
        将敏感词替换为指定字符
        
        Args:
            text: 原始文本
            replace_char: 替换字符，默认为 *
            
        Returns:
            替换后的文本
        """
        if not text:
            return text
        
        result = text
        
        # 使用正则替换
        for pattern in self.patterns:
            matches = pattern.findall(result)
            for match in matches:
                replacement = replace_char * len(match)
                result = result.replace(match, replacement)
        
        return result
    
    def add_words(self, words: List[str], category: str = 'custom'):
        """
        动态添加敏感词
        
        Args:
            words: 敏感词列表
            category: 类别
        """
        if category not in self.word_categories:
            self.word_categories[category] = []
        
        self.word_categories[category].extend(words)
        self.all_words.update(words)
        
        # 重新编译正则
        self._compile_patterns()
        
        logger.info(f"✅ 添加 {len(words)} 个敏感词到类别 {category}")
    
    def get_category_name(self, category: str) -> str:
        """获取类别的中文名称"""
        category_names = {
            'advertising': '广告推广',
            'pornography': '色情低俗',
            'gambling': '赌博',
            'illegal': '违法犯罪',
            'fraud': '诈骗',
            'politics': '时政敏感',
            'abuse': '辱骂侮辱',
            'custom': '自定义'
        }
        return category_names.get(category, '其他违规')


# 🔥 全局敏感词过滤器实例
sensitive_filter = SensitiveWordFilter()


def check_sensitive_content(text: str) -> dict:
    """
    检测敏感内容（供外部调用）
    
    Args:
        text: 要检测的文本
        
    Returns:
        {
            'is_sensitive': bool,
            'matched_words': List[str],
            'category': str,
            'category_name': str,
            'suggestion': str  # 'pass', 'review', 'reject'
        }
    """
    is_sensitive, matched_words, category = sensitive_filter.check_text(text)
    
    # 根据类别决定建议
    suggestion = 'pass'
    if is_sensitive:
        # 严重违规：直接拒绝
        severe_categories = ['pornography', 'gambling', 'illegal', 'politics']
        if category in severe_categories:
            suggestion = 'reject'
        else:
            suggestion = 'review'
    
    return {
        'is_sensitive': is_sensitive,
        'matched_words': matched_words,
        'category': category,
        'category_name': sensitive_filter.get_category_name(category),
        'suggestion': suggestion
    }


if __name__ == '__main__':
    # 测试代码
    test_texts = [
        "正常内容",
        "加我QQ群：123456789",
        "微信号：abc123，加我",
        "这是一个 Q Q 群",  # 变形
        "赌博网站",
        "办假证",
    ]
    
    for text in test_texts:
        result = check_sensitive_content(text)
        print(f"\n文本: {text}")
        print(f"结果: {result}")

